package com.yuyou.fn.settlement.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.settlement.entity.ChangeRecord;
import com.yuyou.fn.settlement.mapper.ChangeRecordMapper;
import com.yuyou.fn.settlement.service.IChangeRecordService;
import com.yuyou.fn.settlement.vo.ChangeRecordQueryVo;
import com.yuyou.fn.settlement.vo.MainAccountAmountVo;
import com.yuyou.fn.settlement.vo.MainAccountCategoryAmountVo;
import com.yuyou.fn.settlement.vo.MainAccountTimeAmountVo;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 *
 * ChangeRecord 表数据服务层接口实现类
 *
 */
@Service
public class ChangeRecordServiceImpl extends SuperServiceImpl<ChangeRecordMapper, ChangeRecord,Long> implements IChangeRecordService {


    @Override
    public List<ChangeRecord> findNotSettleChangeRecord(Long mainAccountId, String subject, Date start, Date end) {

        if(mainAccountId == null || subject == null ){
            throw new BusException("mainAccountId and subject is require");
        }

        Example<ChangeRecord> example = ChangeRecord.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mainAccountId",mainAccountId)
                .andEqualTo("subject",subject)
                .andEqualTo("direction",0)
                .andEqualTo("settleStatus" ,0 );

        if(start != null ){
            criteria.andGreaterThan("effectTime",start);
        }
        if(end != null ){
            criteria.andLessThan("effectTime" , end );
        }
        return findListByExample(example);

    }

    @Override
    public void updateSettleStatus(List<Long> changeRecordIdList, int settleStatus) {
        ChangeRecord changeRecord = new ChangeRecord();
        changeRecord.setSettleStatus(settleStatus);

        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andIn("changeRecordId" ,changeRecordIdList );

        updateSelectiveByExample(changeRecord,example);

    }

    @Override
    public List<ChangeRecord> findChangeRecordByTrackingIdSubject(Long trackingId, String subject, Long mainAccountId) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andEqualTo("subject" , subject ).andEqualTo("trackingId" , trackingId ).andEqualTo("mainAccountId" ,mainAccountId );
        return findListByExample(example);
    }

    @Override
    public List<ChangeRecord> findByMainAccountIdsTimeDirectionSubject(List<Long> mainAccountIds, Date startDate, Date endDate, Integer driection, String subject,String ...columns) {
        if (mainAccountIds==null || mainAccountIds.size()<=0){
            return Collections.EMPTY_LIST;
        }
        Example example=ChangeRecord.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("mainAccountId",mainAccountIds);
        criteria.andGreaterThanOrEqualTo("effectTime",startDate);
        criteria.andLessThanOrEqualTo("effectTime",endDate);
        criteria.andEqualTo("subject",subject);
        criteria.andEqualTo("direction",driection);
        example.orderBy("effectTime");
        if (columns!=null){
            example.selectProperties(columns);
        }
        return findListByExample(example);
    }

    @Override
    public BigDecimal sumBySubjectDirection(Long mainAccountId, int direction, String subject, Date start, Date end) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andEqualTo("mainAccountId" , mainAccountId )
                .andEqualTo("subject" , subject )
                .andGreaterThanOrEqualTo("effectTime" , start )
                .andLessThanOrEqualTo("effectTime",end );

        List<ChangeRecord> list = findListByExample(example);
        BigDecimal sum = BigDecimal.ZERO ;
        for(ChangeRecord changeRecord : list ){
            sum  = sum.add(changeRecord.getAmount());
        }
        return sum;
    }

    @Override
    public BigDecimal sumBySubjectCategoryDirection(Long mainAccountId, int direction, String subject,Long categoryId, Date start, Date end) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andEqualTo("mainAccountId" , mainAccountId )
                .andEqualTo("subject" , subject )
                .andGreaterThanOrEqualTo("effectTime" , start )
                .andLessThanOrEqualTo("effectTime",end )
                .andEqualTo("categoryId",categoryId);
        List<ChangeRecord> list = findListByExample(example);
        BigDecimal sum = BigDecimal.ZERO ;
        for(ChangeRecord changeRecord : list ){
            sum  = sum.add(changeRecord.getAmount());
        }
        return sum;
    }

    @Override
    public List<ChangeRecord> findByCategoryId(int direction,String subject,Date startDate, Date endDate, Long categoryId) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andEqualTo("categoryId" , categoryId )
                .andEqualTo("subject" , subject )
                .andGreaterThanOrEqualTo("effectTime" , startDate )
                .andLessThanOrEqualTo("effectTime",endDate );

        List<ChangeRecord> changeRecordList = findListByExample(example);
        return changeRecordList;
    }

    @Override
    public List<ChangeRecord> findByCategoryIdAndMainAccountId(Long mainAccountId,int direction, String subject, Date startDate, Date endDate, Long categoryId) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andEqualTo("categoryId" , categoryId ).andEqualTo("mainAccountId",mainAccountId)
                .andEqualTo("subject" , subject )
                .andGreaterThanOrEqualTo("effectTime" , startDate )
                .andLessThanOrEqualTo("effectTime",endDate );

        List<ChangeRecord> changeRecordList = findListByExample(example);
        return changeRecordList;
    }

    @Override
    public Page<ChangeRecord> findPageByQueryVo(ChangeRecordQueryVo changeRecordQueryVo, int pageNo, int pageSize) {
        Example<ChangeRecord> example=ChangeRecord.createExample();
        Example.Criteria criteria=example.createCriteria();
        CriteriaUtils.fillCondition(criteria,changeRecordQueryVo);
        return this.findPageByExample(example,pageNo,pageSize);
    }

    @Override
    public List<ChangeRecord> findByCategoryIdsAndMainAccountIds(List<Long> mainAccountIds, int direction, String subject, Date startDate, Date endDate, List<Long> categoryIds) {
        if (mainAccountIds==null || mainAccountIds.size()<=0){
            return Collections.EMPTY_LIST;
        }

        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andIn("categoryId" , categoryIds ).andIn("mainAccountId",mainAccountIds)
                .andEqualTo("subject" , subject )
                .andGreaterThanOrEqualTo("effectTime" , startDate )
                .andLessThanOrEqualTo("effectTime",endDate );

        List<ChangeRecord> changeRecordList = findListByExample(example);
        return changeRecordList;
    }

    @Override
    public List<ChangeRecord> findChangeRecordByTrackingIdSubjectCategoryId(Long trackingId, String subject, long categoryId) {

        Example<ChangeRecord> example = ChangeRecord.createExample();
        example.createCriteria().andEqualTo("categoryId" , categoryId ).andEqualTo("subject" , subject ).andEqualTo("trackingId" , trackingId );

        return findListByExample(example);

    }

    @Override
    public List<MainAccountTimeAmountVo> findMonthAmount(ChangeRecordQueryVo changeRecordQueryVo) {
        return autoMapper.findMonthAmount(changeRecordQueryVo);
    }

    @Override
    public List<MainAccountAmountVo> findMainAccountAmount(ChangeRecordQueryVo changeRecordQueryVo) {
        return autoMapper.findMainAccountAmount(changeRecordQueryVo);
    }

    @Override
    public List<MainAccountCategoryAmountVo> findMainAccountCategoryAmount(ChangeRecordQueryVo changeRecordQueryVo) {
        return autoMapper.findMainAccountCategoryAmount(changeRecordQueryVo);
    }
}